package com.sun.newapp;

import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Environment;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.lang.reflect.Method;
import java.util.UUID;

/**
 * Created by sun on 2019/12/23.
 */
public class DeviceIdUtils {
    private static final String TAG = "DeviceIdUtils";
    /**
     * 读取SD卡中文本文件
     *
     * @param fileName
     * @return
     */
    public static String readSDFile(String fileName) {
        StringBuffer sb = new StringBuffer();
        File file = new File(Environment.getExternalStorageDirectory() + "/" + fileName);
        try {
            FileInputStream fis = new FileInputStream(file);
            int c;
            while ((c = fis.read()) != -1) {
                sb.append((char) c);
            }
            fis.close();
        } catch (FileNotFoundException e) {
//            e.printStackTrace();
            return "";
        } catch (IOException e) {
            return "";
//            e.printStackTrace();
        }
        return sb.toString();
    }
    /**
     * 保存到SD卡
     * @param filename
     * @param filecontent
     * @throws Exception
     */
    public static void saveToSDCard(String filename, String filecontent)throws Exception{
        File file = new File(Environment.getExternalStorageDirectory(),filename);
        FileOutputStream outStream = new FileOutputStream(file);
        outStream.write(filecontent.getBytes());
        outStream.close();
    }
    /**
     * 获取手机IMEI号((International Mobile Equipment Identity,国际移动身份识别码)
     */
    public static String getIMEI(Context context) {
//        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(context.TELEPHONY_SERVICE);
//        String deviceId = telephonyManager.getDeviceId();
        //android 10以上已经获取不了imei了 用 android id代替
//        String deviceId = Settings.System.getString(
//                context.getContentResolver(), Settings.Secure.ANDROID_ID);
//        if(TextUtils.isEmpty(deviceId)){
//            Log.e("TAG","获取IMEI失败");
//            deviceId=UUID.randomUUID().toString();
//        }
        String deviceId=readSDFile("gyt.android");
        if(TextUtils.isEmpty(deviceId)){
            deviceId=UUID.randomUUID().toString();
            try {
                saveToSDCard("gyt.android",deviceId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return  deviceId;
    }
    public static String getLocalDeviceId(Context context) {
        String deviceId=readSDFile("gyt.android");
        if(TextUtils.isEmpty(deviceId)){
            deviceId=UUID.randomUUID().toString();
            try {
                saveToSDCard("gyt.android",deviceId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return  deviceId;
//        String onlyId;
//
//        onlyId = getImei(context);
//        //获取imei号不为空，直接返回
//        if (!TextUtils.isEmpty(onlyId)) {
//            return onlyId;
//        }
////        onlyId = getSnId();
////        //获取设备序列号不为空，直接返回
////        if (!TextUtils.isEmpty(onlyId)) {
////            return onlyId;
////        }
////        onlyId = getCpuName();
////        Log.d(TAG, "getLocalDeviceId: cpu id " + onlyId);
////        //如果获取的cpu串码不为空，直接返回
////        if (!onlyId.equals("0")) {
////            return onlyId;
////        }
////        onlyId = getAndroidId(context);
////        //获取androidID号不为空，直接返回
////        if (!TextUtils.isEmpty(onlyId)) {
////            return onlyId;
////        }
//        onlyId = getPesudoUniqueID();
//        //获取Unique号不为空，直接返回
//        if (!TextUtils.isEmpty(onlyId)) {
//            return onlyId;
//        }
////        onlyId = getWLANMACAddress(context);
//        //获取网络mac不为空，直接返回
////        if (!TimeUtils.isEmpty(onlyId)) {
//////            return onlyId;
////        }
////        onlyId = getBTMACAddress();
////        //获取蓝牙mac号不为空，直接返回
////        if (!TimeUtils.isEmpty(onlyId)) {
//////            return onlyId;
////        }
//        //生成uuid
////        onlyId = getUUID();
//        return onlyId;
    }

    /**
     * 得到全局唯一UUID
     */
    public static String getUUID() {
        String uuid = null;
        uuid = UUID.randomUUID().toString();
        Log.d(TAG, "getUUID: uuid " + uuid);
        return uuid;
    }

    /**
     * The IMEI: 仅仅只对Android手机有效
     * 采用此种方法，需要在AndroidManifest.xml中加入一个许可：android.permission.READ_PHONE_STATE，并且用
     * 户应当允许安装此应用。作为手机来讲，IMEI是唯一的，它应该类似于 359881030314356（除非你有一个没有量产的手
     * 机（水货）它可能有无效的IMEI，如：0000000000000）。
     *
     * @return imei
     */
    public static String getImei(Context context) {
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        String imei = null;
        try {
            imei = tm.getDeviceId();
        } catch (Exception e) {
            Log.d(TAG, "getImei: error " + e.toString());
        }
        Log.d(TAG, "getImei: imei " + imei);
        return imei;
    }

    //获取设备序列号
    public static String getSnId() {
        String str = null;
        try {
            Class<?> c = Class.forName("android.os.SystemProperties");
            Method get = c.getMethod("get", String.class, String.class);
            String serialnum = (String) (get.invoke(c, "ro.serialno", "unknown"));
            Log.d(TAG, "getOnlyId:sn: " + serialnum);
            return serialnum;
        } catch (Exception ignored) {

        }
        return str;
    }

    /**
     * 获取cpu串码
     *
     * @return
     */
    public static String getCpuName() {
        String str = "", strCPU = "", cpuAddress = "0";

        try {
//读取CPU信息

            Process pp = Runtime.getRuntime().exec("cat /proc/cpuinfo");

            InputStreamReader ir = new InputStreamReader(pp.getInputStream());

            LineNumberReader input = new LineNumberReader(ir);

//查找CPU序列号

            for (int i = 1; i < 100; i++) {

                str = input.readLine();

                if (str != null) {

//查找到序列号所在行

                    if (str.indexOf("Serial") > -1) {

//提取序列号

                        strCPU = str.substring(str.indexOf(":") + 1, str.length());

//去空格

                        cpuAddress = strCPU.trim();

                        break;

                    }
                } else {

//文件结尾
                    break;

                }
            }

        } catch (IOException ex) {

//赋予默认值

            ex.printStackTrace();
        }
        return cpuAddress;

    }

    /**
     * The Android ID
     * 通常被认为不可信，因为它有时为null。开发文档中说明了：这个ID会改变如果进行了出厂设置。并且，如果某个
     * Andorid手机被Root过的话，这个ID也可以被任意改变。无需任何许可。
     *
     * @return AndroidID
     */
    public static String getAndroidId(Context context) {
        String str = null;
        try {
            str = Settings.System.getString(context.getContentResolver(), Settings.System.ANDROID_ID);
        } catch (Exception e) {
            Log.d(TAG, "getAndroidId: error " + e.toString());
        }
        Log.d(TAG, "getAndroidId: " + str);
        return str;
    }

    public static String getSerialNum() {
        String serialNumber = null;
        try {
            serialNumber = Build.SERIAL;
        } catch (Exception e) {
            Log.d(TAG, "getSerialNum: error " + e.toString());
        }
        Log.d(TAG, "getSerialNum: " + serialNumber);
        return serialNumber;
    }

    /**
     * Pseudo-Unique ID, 这个在任何Android手机中都有效
     * 有一些特殊的情况，一些如平板电脑的设置没有通话功能，或者你不愿加入READ_PHONE_STATE许可。而你仍然想获得唯
     * 一序列号之类的东西。这时你可以通过取出ROM版本、制造商、CPU型号、以及其他硬件信息来实现这一点。这样计算出
     * 来的ID不是唯一的（因为如果两个手机应用了同样的硬件以及Rom 镜像）。但应当明白的是，出现类似情况的可能性基
     * 本可以忽略。大多数的Build成员都是字符串形式的，我们只取他们的长度信息。我们取到13个数字，并在前面加上“35
     * ”。这样这个ID看起来就和15位IMEI一样了。
     *
     * @return PesudoUniqueID
     */
    public static String getPesudoUniqueID() {
        String m_szDevIDShort = "35" + //we make this look like a valid IMEI
                Build.BOARD.length() % 10 +
                Build.BRAND.length() % 10 +
                Build.CPU_ABI.length() % 10 +
                Build.DEVICE.length() % 10 +
                Build.DISPLAY.length() % 10 +
                Build.HOST.length() % 10 +
                Build.ID.length() % 10 +
                Build.MANUFACTURER.length() % 10 +
                Build.MODEL.length() % 10 +
                Build.PRODUCT.length() % 10 +
                Build.TAGS.length() % 10 +
                Build.TYPE.length() % 10 +
                Build.USER.length() % 10; //13 digits
        Log.d(TAG, "getPesudoUniqueID: " + m_szDevIDShort);
        return m_szDevIDShort;
    }

    /**
     * The WLAN MAC Address string
     * 是另一个唯一ID。但是你需要为你的工程加入android.permission.ACCESS_WIFI_STATE 权限，否则这个地址会为
     * null。Returns: 00:11:22:33:44:55 (这不是一个真实的地址。而且这个地址能轻易地被伪造。).WLan不必打开，
     * 就可读取些值。
     *
     * @return m_szWLANMAC
     */
    public static String getWLANMACAddress(Context context) {
        WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();
        Log.d(TAG, "getWLANMACAddress: " + m_szWLANMAC);
        return m_szWLANMAC;
    }

    /**
     * 获取蓝牙mac地址
     * 只在有蓝牙的设备上运行。并且要加入android.permission.BLUETOOTH 权限.Returns: 43:25:78:50:93:38 .
     * 蓝牙没有必要打开，也能读取。
     *
     * @return m_szBTMAC
     */
    public static String getBTMACAddress() {
        BluetoothAdapter m_BluetoothAdapter = null; // Local Bluetooth adapter
        m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        String m_szBTMAC = m_BluetoothAdapter.getAddress();
        Log.d(TAG, "getBTMACAddress: " + m_szBTMAC);
        return m_szBTMAC;
    }

}
